﻿using System;
using System.ComponentModel;
using System.Drawing;
using Microsoft.WowAddonStudio.FrameXml.Components.Designers;
using Microsoft.WowAddonStudio.FrameXml.Components.Support;
using Microsoft.WowAddonStudio.FrameXml.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Microsoft.WowAddonStudio.Services;

namespace Microsoft.WowAddonStudio.FrameXml.Components
{
	[Designer(typeof (LayoutFrameControlDesigner))]
	public partial class LayoutFrameControl : FrameXmlControl<LayoutFrame>
	{
	    /// <summary>
		/// Initializes a new instance of the <see cref="LayoutFrameControl"/> class.
		/// </summary>
		public LayoutFrameControl()
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="LayoutFrameControl"/> class.
		/// </summary>
		/// <param name="layoutFrame">The layout frame.</param>
		public LayoutFrameControl(LayoutFrame layoutFrame)
			: base(layoutFrame)
		{
		}

		/// <summary>
		/// Gets the type of the serialization object this control manages.
		/// </summary>
		public override Type SerializationObjectType
		{
			get { return typeof (LayoutFrame); }
		}

		/// <summary>
		/// Gets the <see cref="LayoutFrame"/>.
		/// </summary>
		public LayoutFrame LayoutFrame
		{
			get { return SerializationObject as LayoutFrame; }
		}

		/// <summary>
		/// Gets a value indicating whether the control or its parent is hidden.
		/// </summary>
		public bool IsHidden
		{
			get
			{
				var parent = Parent as LayoutFrameControl;
                return LayoutFrame.LayoutHidden || (parent != null && parent.IsHidden);
			}
		}

		/// <summary>
		/// Called after the control has been added to another container.
		/// </summary>
		protected override void InitLayout()
		{
			// The parent has changed, initialize the name
			InitializeName();

			// Continue with InitLayout
			base.InitLayout();
		}

        /// <summary>
        /// Draws a placeholder in place of the FrameXML control.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="rectangle"></param>
        public override void DrawPlaceholder(FrameXmlGraphics graphics, Rectangle rectangle)
        {
            base.DrawPlaceholder(graphics, rectangle);

            graphics.DrawPlaceholder(LayoutFrame, this.Font, rectangle);
        }

		/// <summary>
		/// Called when the <see cref="SerializationObject"/>'s property changes.
		/// </summary>
		/// <param name="e">A <see cref="PropertyChangedEventArgs"/> that contains the event data.</param>
		protected override void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);

			switch (e.PropertyName)
			{
				case "Name":
			        InitializeName();
					RefreshPropertyBrowser();
					break;
				case "SizeDimension":
				case "Size":
					LayoutEngine.Layout(this, e.PropertyName);
					UpdateDesignerSelection();
					break;
				case "Anchors":
					LayoutEngine.InitLayout(this);
					LayoutEngine.Layout(this, e.PropertyName);
					UpdateDesignerSelection();
					break;
				case "Virtual":
                    InitializeVirtualControl();
			        break;
				case "Hidden":
					NotifyPropertyValueUIItemsChanged();
					RefreshPropertyBrowser();
					break;
				case "Backdrop":
					Invalidate();
					break;
				case "InheritedObject":
					break;
				case "Inherits":
					//Lock control if inherited
					LockControl(IsInherited);

					//Gets the FrameXmlComponentFactory service instance
					var service = (FrameXmlComponentFactory) GetService(typeof (FrameXmlComponentFactory));
					if (service != null)
					{
						//Reinitialize all subcontrols (inherited and manually added)
                        service.ReinitializeComponent(this);

						//Notify listeners about 'Inherits' property changed
						NotifyPropertyValueUIItemsChanged();
                        
                        // Updates the designer section.
                        UpdateDesignerSelection();
					}
					break;
                case "LayoutHidden":
			        UpdateDesignerSelection();
			        break;
			}
            
		    SetDirtyFlag();
		}

        /// <summary>
        /// Initializes the virtual control.
        /// </summary>
        private void InitializeVirtualControl()
        {
            var inheritableObject = (InheritableObject)((IFrameXmlComponent)this).SerializationObject;
            if (inheritableObject.Virtual)
            {
                var parent = this.Parent;

                // Find Ui.
                while (parent.GetType() != typeof(UiControl))
                    parent = parent.Parent;

                // Sets the new parent of the control.
                this.Parent = parent;

                NotifyPropertyValueUIItemsChanged();
                UpdateDesignerSelection();
            }
            
            if (this.Parent.GetType() == typeof (UiControl) && this.SerializationObject is LayoutFrame)
                ((Ui) ((UiControl) this.Parent).SerializationObject).ResetItem((LayoutFrame) this.SerializationObject);

            EditControl();
        }

        /// <summary>
        /// Edits the control.
        /// </summary>
        private void EditControl()
        {
            var layoutControllerService = this.GetService<ILayoutControllerService>();
            if (layoutControllerService != null)
                layoutControllerService.EditControl(this);
        }
	}
}